﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace FrameWork.Core.ThreadPool
{
    public class TaskGroupPool
    {
        #region ___单列___
        private static TaskGroupPool instance = null;
        private static object obj = new object();
        public static TaskGroupPool Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (obj)
                    {
                        if (instance == null)
                        {
                            instance = new TaskGroupPool();
                        }
                    }
                }
                return instance;
            }
        }
        #endregion

        #region ___字段___
        List<TaskPools> m_ListTaskPool = new List<TaskPools>();
        #endregion

        #region ___方法___
        /// <summary>
        /// 清空线程池
        /// </summary>
        public void Clear(int groupID)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null != taskPool)
                taskPool.Clear();
        }
        /// <summary>
        /// 独占线程池
        /// </summary>
        /// <param name="func"></param>
        /// <param name="cts"></param>
        /// <param name="groupID"></param>
        public void Monopoly(Action func, CancellationTokenSource cts = null, int groupID = 1000)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null == taskPool)
            {
                taskPool = new TaskPools() { GroupId = groupID };
                m_ListTaskPool.Add(taskPool);
            }
            if (taskPool.ThreadCount == 0)
                taskPool.Enqueue(func, cts);
        }
        /// <summary>
        /// 添加任务信息
        /// </summary>
        /// <param name="func"></param>
        /// <param name="cts"></param>
        /// <param name="groupID"></param>
        public void Enqueue(Action func, CancellationTokenSource cts = null, int groupID = 1000)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null == taskPool)
            {
                taskPool = new TaskPools() { GroupId = groupID };
                m_ListTaskPool.Add(taskPool);
            }
            taskPool.Enqueue(func, cts);
        }
        /// <summary>
        /// 阻塞等待多任务完成
        /// </summary>
        /// <param name="func"></param>
        /// <param name="cts"></param>
        /// <param name="groupID"></param>
        public void Enqueue(IEnumerable<Action> actions, int groupID = 1000)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null == taskPool)
            {
                taskPool = new TaskPools() { GroupId = groupID };
                m_ListTaskPool.Add(taskPool);
            }
            taskPool.Enqueue(actions);
        }
        /// <summary>
        /// 阻塞等待多任务完成
        /// </summary>
        /// <param name="func"></param>
        /// <param name="cts"></param>
        /// <param name="groupID"></param>
        public void Enqueue(IEnumerable<Action> actions, Action notice, int groupID = 1000)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null == taskPool)
            {
                taskPool = new TaskPools() { GroupId = groupID };
                m_ListTaskPool.Add(taskPool);
            }
            taskPool.Enqueue(actions, notice);
        }
        /// <summary>
        /// 阻塞等待多任务完成
        /// </summary>
        /// <param name="func"></param>
        /// <param name="cts"></param>
        /// <param name="groupID"></param>
        public void Enqueue(Action condition, Action after, int groupID = 3000)
        {
            var taskPool = m_ListTaskPool.Where(t => t.GroupId == groupID).FirstOrDefault();
            if (null == taskPool)
            {
                taskPool = new TaskPools() { GroupId = groupID };
                m_ListTaskPool.Add(taskPool);
            }
            taskPool.Enqueue(condition, after);
        }
        #endregion
    }
}
